#ifndef YOOHOO_XMPPCORE_CONNECTOR_H
#define YOOHOO_XMPPCORE_CONNECTOR_H

#include "xmppcore/xmppxmlparser.h"
#include "xmppcore/server.h"

#include <QtCore/QObject>
#include <QtNetwork/QAbstractSocket>
#include <QtCore/QList>
#include <QtCrypto>
#include <QtCore/QMutex>
#include <QtCore/QPointer>


class QTcpSocket;
class QTextStream;

using namespace QCA;

namespace yoohoo_xmppcore {

class TlsCallback;

class Connector : public QObject {
	Q_OBJECT
public:
	enum TlsState {
		TlsStateNone,
		TlsStateNegotiating,
		TlsStateEstablished
	};
	Connector(Server& server, TlsCallback* tlsCallback = 0, QObject* parent = 0);
	~Connector();
	void setTlsCallback(TlsCallback* tlsCallback);
	const Server* const server() const;

public slots:
	void connectToHost();
	void disconnectFromHost();
	void write(QString message);
	void startTls();

private slots:
	void socketReadyRead();
	void changeSocketState(QAbstractSocket::SocketState socketState);
	void tlsClosed();
	void tlsError();
	void tlsCertificateRequested();
	void tlsHandshaken();
	void tlsPeerCertificateAvailable();
	void tlsReadyRead();
	void tlsReadyReadOutgoing();

signals:
	void received(QString message);
	void abandonData(int length);
	void socketReady();
	void tlsReady();
	void socketError(QAbstractSocket::SocketError error);
	void socketStateChanged(QAbstractSocket::SocketState state);
	void tlsError(int errorCode);

private:
	void parseAndProcessReceivedData(QString& dataReceived);
	void processXmls(QList<QString> xmls);

private:
	QPointer<QTcpSocket> _socket;
	QTextStream* _textStream;
	QPointer<TlsCallback> _tlsCallback;
	Server* _server;
	quint16 _maxPacketLength;
	XmppXmlParser _parser;
	QPointer<TLS> _tls;
	QMutex _socketWriteLock;
	QAbstractSocket::SocketState _socketState;
	TlsState _tlsState;

	static const quint16 DEFAULT_MAX_PACKET_LENGTH;
};

}

#endif
